﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Xml.Linq;
using AxMSTSCLib;
using EasierRdp.Base;
using EasierRdp.Util;
using MSTSCLib;

namespace EasierRdp.Models
{
    class RdpSession : RdpModel
    {
        private readonly RdpUser _user;
        private readonly RdpServer _target;
        private RdpSetting _setting;

        public event EventHandler RequestExitFullScreen;
        public event EventHandler RequestMiniSize;
        public readonly Panel Container = new Panel { Dock = DockStyle.Fill };
        public readonly AxMsRdpClient8NotSafeForScripting Control = new AxMsRdpClient8NotSafeForScripting { Dock = DockStyle.Fill };

        public override IEnumerable<INode> Children
        {
            get
            {
                return Enumerable.Empty<INode>();
            }
        }

        public override XElement ToXml()
        {
            throw new NotImplementedException();
        }

        public RdpServer Target { get { return _target; } }

        public RdpUser User { get { return _user; } }

        public int Width { get { return Control.Width; }}

        public RdpSetting Setting
        {
            get { return _setting; }
        }

        public bool Connected
        {
            get { return Convert.ToBoolean(Control.Connected); }
        }

        public RdpSession(RdpServer server, RdpUser user)
        {
            if (server == null)
            {
                throw  new ArgumentNullException("server");
            }
            if (user == null)
            {
                throw new ArgumentNullException("user");
            }
            _target = server;
            _user = user;
            Name = String.Format("{0}@{1}", _user.Name, server.Name);
            Control.OnRequestLeaveFullScreen += OnExitFullScreen;
            Control.OnRequestContainerMinimize += OnMiniSize;
            Container.Controls.Add(Control);
        }

        public bool With(RdpServer server, RdpUser user)
        {
            return _user == user && _target == server;
        }

        public void Connect(RdpSetting setting = null)
        {
            if (!Connected)
            {
                Control.Server = _target.Name;
                Control.UserName = _user.Name;
                Control.AdvancedSettings4.RDPPort = _target.Port ?? 3389;
                var secured = (IMsTscNonScriptable) Control.GetOcx();
                secured.ClearTextPassword = _user.Password;
                if (setting != null)
                {
                    _setting = setting;
                    if (_setting.Width.HasValue)
                    {
                        Control.DesktopWidth = _setting.Width.Value;
                    }
                    if (_setting.Height.HasValue)
                    {
                        Control.DesktopHeight = _setting.Height.Value;
                    }
                }
                Control.Connect();
            }
            Show();
        }

        public void Disconnect()
        {
            if (Connected)
            {
                Control.Disconnect();
            }
        }

        public void Show()
        {
            if (Container.Parent != null)
            {
                foreach (Control control in Container.Parent.Controls)
                {
                    control.Visible = false;
                }
            }
            Container.BringToFront();
            Container.Visible = true;
            RdpContext.FrontSession = this;
        }

        public void SwichFullScreen()
        {
            Control.FullScreen = !Control.FullScreen;
        }

        public void OnMiniSize(object sender, EventArgs e)
        {
            if (RequestMiniSize != null)
            {
                RequestMiniSize(sender, e);
            }
        }

        public void OnExitFullScreen(object sender, EventArgs e)
        {
            if(RequestExitFullScreen != null)
            {
                RequestExitFullScreen(sender,e);
            }
        }

        public void OnConnected(object sender, EventArgs e)
        {
        }

        public void OnDisconnected(object sender, EventArgs e)
        {
            OnExitFullScreen(sender, e);
        }
        
        public void ApplySetting(RdpSetting setting)
        {
            if (setting != null)
            {
                if (_setting == null || _setting.Width != setting.Width || _setting.Height != setting.Height)
                {
                    Control.Reconnect((uint)(setting.Width ?? 0), (uint)(setting.Height ?? 0));
                }
                _setting = setting;
            }
        }
    }
}
